﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Threading;

namespace XMM.Controls.Library
{
    /// <summary>
    /// Interaktionslogik für Details_Season.xaml
    /// </summary>
    public partial class Details_Season : UserControl
    {
        Objects.SeriesSeason SelectedSeason { get; set; }
        Objects.Series SelectedShow
        {
            get
            {
                return new Objects.Series(SelectedSeason.SeriesID);
            }
        }

        Objects.MediaInfo CurrentPlayback
        {
            get
            {
                return ParentLibrary.CurrentPlayback;
            }
            set
            {
                ParentLibrary.CurrentPlayback = value;
            }
        }

        bool IsPlaying
        {
            get
            {
                return ParentLibrary.IsPlaying;
            }
            set
            {
                ParentLibrary.IsPlaying = value;
            }
        }

        XMM.Library ParentLibrary { get; set; }

        public Objects.SeriesEpisode SelectedEpisode
        {
            get
            {
                return (Objects.SeriesEpisode)lbEpisodes.SelectedItem;
            }
        }

        public Details_Season(XMM.Library dlgParentLibrary, Objects.SeriesSeason oSelectedSeason)
        {
            InitializeComponent();

            SelectedSeason = oSelectedSeason;
            ParentLibrary = dlgParentLibrary;

            loadDetails();
        }

        public void loadDetails()
        {
            // Clear Episode-Details.
            svEpisodeDetails.Content = null;

            /********************************************
             * Load Show-Info.
             * */
            lblShowTitle.Content = SelectedShow.Name;

            // Load Poster or default image
            string sCoverPath = new Settings().LibraryDataStorage + "series\\images\\xmm_" + SelectedShow.SeriesID.ToString() + ".jpg";
            if (System.IO.File.Exists(sCoverPath))
            {
                imgPoster.Source = new BitmapImage(new Uri(sCoverPath, UriKind.Absolute));
                imgPoster.Stretch = Stretch.Uniform;
            }
            imgPoster.VerticalAlignment = System.Windows.VerticalAlignment.Center;
            imgPoster.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;

            // Check Base-Dir
            if (SelectedSeason.BaseDirectory != null && SelectedSeason.BaseDirectory != String.Empty)
            {
                if (System.IO.Directory.Exists(SelectedSeason.BaseDirectory))
                {
                    btnEditBaseDir.ToolTip = "(ONLINE) Basis-Verzeichnis: " + SelectedSeason.BaseDirectory;
                    imgBaseDirStatus.Source = new BitmapImage(new Uri(Tools.getInstallationPath() + @"\images\bin\folder_ok.png", UriKind.Absolute));
                }
                else
                {
                    btnEditBaseDir.ToolTip = "(OFFLINE) Basis-Verzeichnis: " + SelectedSeason.BaseDirectory;
                    imgBaseDirStatus.Source = new BitmapImage(new Uri(Tools.getInstallationPath() + @"\images\bin\folder_missing.png", UriKind.Absolute));
                }
            }
            else
            {
                btnEditBaseDir.ToolTip = "Kein Basis-Verzeichnis definiert!";
                imgBaseDirStatus.Source = new BitmapImage(new Uri(Tools.getInstallationPath() + @"\images\bin\folder_undefined.png", UriKind.Absolute));
            }

            /********************************************
             * Load Episodes
             * */
            lbEpisodes.Items.Clear();
            if (SelectedSeason.Episodes.Count > 0)
            {
                int iCurrentIndex = 0;
                foreach (Objects.SeriesEpisode oEpisode in SelectedSeason.Episodes)
                {
                    if (ParentLibrary.SelectedAudition != null && oEpisode.SeenBy(ParentLibrary.SelectedAudition.AuditionID))
                    {
                        if (oEpisode.Name.Contains("√ ") == false)
                        {
                            oEpisode.Name = "√ " + oEpisode.Name;
                            
                        }
                        
                    }
                    lbEpisodes.Items.Add(oEpisode);

                    ++iCurrentIndex;
                }
            }
        }

        private void lbEpisodes_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (lbEpisodes.SelectedIndex > -1)
            {
                if (IsPlaying)
                {
                    MessageBox.Show("Es läuft bereits eine Wiedergabe! Beenden Sie zuerst das laufende Video.", "Parallele Wiedergaben", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                    return;
                }

                IsPlaying = true;

                Objects.SeriesEpisode oEpisode = (Objects.SeriesEpisode)lbEpisodes.SelectedItem;
                StartPlaybackThread(oEpisode);
            }
        }

        public void StartPlaybackThread(Objects.SeriesEpisode oEpisode)
        {
            Objects.SeriesSeason oSeason = new Objects.SeriesSeason(oEpisode.SeasonID);

            ParentLibrary.updateStatus("Es läuft: " + Objects.Series.getTitle(oEpisode.SeriesID) + " - S" + oSeason.Number.ToString() + " E" + oEpisode.EpisodeNo.ToString() + " - " + oEpisode.Name, true);

            CurrentPlayback = new Objects.MediaInfo();
            CurrentPlayback.FullPath = oEpisode.MediaFile;
            CurrentPlayback.UserdefinedMediaInfo = oEpisode;
            CurrentPlayback.MediaType = 1;

            ParameterizedThreadStart oThreadStart = new ParameterizedThreadStart(startVLCPlayerEpisode);
            Thread thEpisodePlayback = new Thread(oThreadStart);
            thEpisodePlayback.Start(oEpisode);
        }

        public void startVLCPlayerEpisode(Object oEpisode)
        {
            Settings oSettings = new Settings();
            oSettings.Load();

            Objects.SeriesEpisode Episode = (Objects.SeriesEpisode)oEpisode;

            if (System.IO.File.Exists(Episode.MediaFile) == false)
            {
                // Drop CurrentPlayback-Value & Playback-Status.
                CurrentPlayback = null;
                IsPlaying = false;
                MessageBox.Show("Die Datei \"" + Episode.MediaFile + "\" wurde nicht gefunden!", "Medium nicht gefunden", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }

            if (System.IO.File.Exists(oSettings.VLCExecutablePath) == false)
            {
                CurrentPlayback = null;
                IsPlaying = false;
                MessageBox.Show("Das angegebene Abspielprogram (\"" + oSettings.VLCExecutablePath + "\") wurde nicht gefunden! Bitte überprüfen Sie Ihre Einstellungen!", "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }


            System.Diagnostics.Process pVLCPlayer = new System.Diagnostics.Process();
            pVLCPlayer.StartInfo = new System.Diagnostics.ProcessStartInfo();
            pVLCPlayer.StartInfo.FileName = oSettings.VLCExecutablePath;
            if (oSettings.VideoPlayerExtensions == 1)
            {
                pVLCPlayer.StartInfo.Arguments = "--fullscreen --play-and-exit ";
            }
            pVLCPlayer.StartInfo.Arguments += "\"" + Episode.MediaFile + "\"";
            pVLCPlayer.Start();

            pVLCPlayer.WaitForExit();

            // Create playback record.
            Objects.PlaybackHistoryRecord.CreateRecord(ParentLibrary.SelectedAudition.AuditionID, 2, Episode.EpisodeID);

            // Reload Playback-History.
            Dispatcher.Invoke(new getEpisodeHistoryCallback(ParentLibrary.getEpisodeHistory), new object[] { Episode });

            // Refresh Item State.
            Dispatcher.Invoke(new setSeenCallback(ParentLibrary.setEpisodeSeen));

            // Update Audition.
            ParentLibrary.SelectedAudition.LastMediaID = Episode.EpisodeID;
            ParentLibrary.SelectedAudition.LastMediaType = 2;
            ParentLibrary.SelectedAudition.SaveChanges();

            // Update Season-Details.
            Dispatcher.Invoke(new updateEpisodeListEntryCallback(updateEpisodeListEntry), new object[] { oEpisode });

            // Drop CurrentPlayback-Value & Playback-Status.
            CurrentPlayback = null;
            IsPlaying = false;

            // Toggle Status.
            this.Dispatcher.Invoke(new updateStatusCallback(ParentLibrary.updateStatus), new object[] { "Bereit...", false });
        }

        private void updateEpisodeListEntry(Objects.SeriesEpisode oEpisode)
        {
            int iIndex = lbEpisodes.Items.IndexOf(oEpisode);
            if (iIndex > -1)
            {
                ((Objects.SeriesEpisode)lbEpisodes.Items[iIndex]).Name = "√ " + oEpisode.Name;
                lbEpisodes.Items.Refresh();
            }
        }

        private delegate void updateEpisodeListEntryCallback(Objects.SeriesEpisode oEpisode);

        public delegate void updateStatusCallback(string sNewStatusMessage, bool bEnableProgressAnimation);

        private delegate void setSeenCallback();

        private delegate void getEpisodeHistoryCallback(Objects.SeriesEpisode oSelectedEpisode);

        private void lbEpisodes_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (lbEpisodes.SelectedIndex > -1)
            {
                //SelectedEpisode = (Objects.SeriesEpisode)lbEpisodes.SelectedItem;
                ParentLibrary.SelectedEpisode = SelectedEpisode;
                ParentLibrary.getEpisodeHistory(SelectedEpisode);


                Details_Episode cEpisodeDetails = new Details_Episode(this, SelectedEpisode.EpisodeID);
                svEpisodeDetails.Content = cEpisodeDetails;
            }
            else
            {
                //SelectedEpisode = null;
                ParentLibrary.SelectedEpisode = null;
            }
        }

        private void cmiSetSeen_Click(object sender, RoutedEventArgs e)
        {
            //int iSelectedIndex = lbEpisodes.SelectedIndex;

            if (lbEpisodes.SelectedItems != null && lbEpisodes.SelectedItems.Count > 0)
            {
                int iSuccessfull = 0;
                int iFailed = 0;

                foreach (Objects.SeriesEpisode oEpisode in lbEpisodes.SelectedItems)
                {
                    if (Objects.PlaybackHistoryRecord.CreateRecord(ParentLibrary.SelectedAudition.AuditionID, 2, oEpisode.EpisodeID))
                        ++iSuccessfull;
                    else
                        ++iFailed;
                }

                if (iFailed > 0)
                {
                    string sMessage = "Als gesehen markiert:" + Environment.NewLine;
                    sMessage += "Erfolgreich:   " + iSuccessfull.ToString() + Environment.NewLine;
                    sMessage += "Fehlgeschlagen:" + iFailed.ToString() + Environment.NewLine;

                    MessageBox.Show(sMessage, "Nicht alle Episoden wurden markiert", MessageBoxButton.OK, MessageBoxImage.Warning);
                }

                loadDetails();

                /*
                lbEpisodes.SelectedIndex = iSelectedIndex;
                lbEpisodes_SelectionChanged(null, null);
                 * */
            }
        }

        private void cmiSetDriveLetter_Click(object sender, RoutedEventArgs e)
        {
            int iSelectedIndex = lbEpisodes.SelectedIndex;
            if (lbEpisodes.SelectedItems != null && lbEpisodes.SelectedItems.Count > 0)
            {
                Dialoges.Library.ChangeDriveLetter dlgChangeDriveLetter = new Dialoges.Library.ChangeDriveLetter(((Objects.SeriesEpisode)lbEpisodes.SelectedItems[0]).MediaFile.Substring(0, 1));
                if ((bool)dlgChangeDriveLetter.ShowDialog())
                {
                    foreach (Objects.SeriesEpisode oEpisode in lbEpisodes.SelectedItems)
                    {
                        oEpisode.RelocateHDD(dlgChangeDriveLetter.NewDriveLetter);
                    }
                }


                loadDetails();

                lbEpisodes.SelectedIndex = iSelectedIndex;
                lbEpisodes_SelectionChanged(null, null);
            }
        }

        private void btnEditBaseDir_Click(object sender, RoutedEventArgs e)
        {
            System.Windows.Forms.FolderBrowserDialog dlgBrowseBaseDir = new System.Windows.Forms.FolderBrowserDialog();
            dlgBrowseBaseDir.ShowNewFolderButton = true;

            if (dlgBrowseBaseDir.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                if (SelectedSeason.BaseDirectory != null && SelectedSeason.BaseDirectory != String.Empty)
                {
                    string sMessage = "Möchten Sie das Basisverzeichnis wirklich ändern?" + Environment.NewLine + Environment.NewLine;
                    sMessage += "Aktuell: " + SelectedSeason.BaseDirectory + Environment.NewLine;
                    sMessage += "Neu:     " + dlgBrowseBaseDir.SelectedPath + "\\";
                    if (MessageBox.Show(sMessage, "Basisverzeichnis ändern", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.No)
                        return;
                }

                SelectedSeason.BaseDirectory = dlgBrowseBaseDir.SelectedPath + "\\";
                SelectedSeason.SaveChanges();

                loadDetails();
            }
        }

        private void cmiRelocateFile_Click(object sender, RoutedEventArgs e)
        {
            if (lbEpisodes.SelectedItems != null && lbEpisodes.SelectedItems.Count > 0)
            {
                if (MessageBox.Show("Möchten Sie die ausgewählten " + lbEpisodes.SelectedItems.Count.ToString() + " Folgen neu verknüpfen?", "Dateiverknüpfungen ändern", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.Yes)
                {
                    //Dictionary<Objects.SeriesEpisode, bool> dicSelectedEpisodes = new Dictionary<Objects.SeriesEpisode, bool>();
                    string sMessage = "Durchgeführten Änderungen:" + Environment.NewLine + Environment.NewLine;
                    
                    /*List<Objects.SeriesEpisode> lSelectedEpisodes = new List<Objects.SeriesEpisode>();
                    List<string> lEpisodeStats = new List<string>();*/

                    foreach (Objects.SeriesEpisode oEpisode in lbEpisodes.SelectedItems)
                    {
                        Objects.Series oShow = new Objects.Series(oEpisode.SeriesID);
                        Objects.SeriesSeason oSeason = new Objects.SeriesSeason(oEpisode.SeasonID);
                        //lSelectedEpisodes.Add(oEpisode);

                        System.Windows.Forms.OpenFileDialog dlgBrowseNewFile = new System.Windows.Forms.OpenFileDialog();
                        dlgBrowseNewFile.Title = oShow.Name + " S" + oSeason.Number.ToString() + " E" + oEpisode.EpisodeNo.ToString() + " auswählen";
                        dlgBrowseNewFile.InitialDirectory = oEpisode.MediaFile.Substring(oEpisode.MediaFile.LastIndexOf('\\'));
                        dlgBrowseNewFile.Multiselect = false;
                        dlgBrowseNewFile.RestoreDirectory = true;

                        if (dlgBrowseNewFile.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                        {
                            oEpisode.MediaFile = dlgBrowseNewFile.FileName;
                            if (oEpisode.SaveChanges())
                                sMessage += "OK - " + oShow.Name + " (S" + oSeason.Number.ToString() + " E" + oEpisode.EpisodeNo.ToString() + ")" + Environment.NewLine;
                                //dicSelectedEpisodes.Add(oEpisode, true);
                            else
                                sMessage += "FEHLER - " + oShow.Name + " (S" + oSeason.Number.ToString() + " E" + oEpisode.EpisodeNo.ToString() + ")" + Environment.NewLine;
                                //dicSelectedEpisodes.Add(oEpisode, false);
                        }
                    }

                    loadDetails();
                    MessageBox.Show(sMessage, "Änderungen durchgeführt", MessageBoxButton.OK, MessageBoxImage.Information);
                }
            }
        }

        private void cmiDeleteEpisode_Click(object sender, RoutedEventArgs e)
        {
            if (lbEpisodes.SelectedItems != null && lbEpisodes.SelectedItems.Count > 0)
            {
                if (MessageBox.Show("Möchten Sie die " + lbEpisodes.SelectedItems.Count.ToString() + " Folgen wirklich löschen?", "Ausgewählte Folgen löschen", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.Yes)
                {
                    int iDeleteCount = 0;
                    int iTotalCount = lbEpisodes.SelectedItems.Count;

                    foreach (Objects.SeriesEpisode oEpisode in lbEpisodes.SelectedItems)
                    {
                        if (oEpisode.Delete())
                        {
                            ++iDeleteCount;
                        }
                    }

                    MessageBox.Show(iDeleteCount.ToString() + " von " + iTotalCount.ToString() + " gelöscht!", "Folgen gelöscht", MessageBoxButton.OK, MessageBoxImage.Information);
                    SelectedSeason = new Objects.SeriesSeason(SelectedSeason.SeasonID);
                    loadDetails();
                }
            }
        }
    }
}
